#include<stdio.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<unistd.h>
#include<errno.h>
#include<string.h>
#include<stdlib.h>
#include <arpa/inet.h>
 
#define SERVER_PORT 4321
 
 
int main()
{
	int sock_fd;                    //套接字描述符
	int recv_num;
	int send_num;
	char recv_buf[20] = {0};
    char ack_buf[20] = "rev success";
	struct sockaddr_in addr_server;     //服务端地址
	struct sockaddr_in addr_client;     //客户端地址
    socklen_t client_addrlen;
 
    //AF_INET指定通信协议族(IPV4、IPV6等),SOCK_DGRAM表示socket类型(面向流的TCP取SOCK_STREAM，面向数据报的UDP取SOCK_DGRAM)
    //第三个参数protocol通常设置为0，表示为给定的通信域和套接字类型选择默认协议
	sock_fd = socket(AF_INET,SOCK_DGRAM,0);     //创建套接字文件描述符，调用成功返回有效文件描述符，失败返回-1并设置errno   
	if(sock_fd < 0)
    {
		perror("socket error");
		exit(1);
	} else
    {
		printf("creat udp socket sucess\n");
	}
	//初始化服务器端地址
	memset(&addr_server,0,sizeof(struct sockaddr_in));
	addr_server.sin_family = AF_INET;                 //协议族
	addr_server.sin_port = htons(SERVER_PORT);        //端口号，htons转换字节序
	// addr_serv.sin_addr.s_addr = htonl(INADDR_ANY);  //任意本地址,服务器所有网卡IP地址
    addr_server.sin_addr.s_addr=inet_addr("192.168.2.136");		//IP地址字符串格式转换为二进制格式
	
	client_addrlen = sizeof(struct sockaddr_in);
	//绑定套接字
	if(bind(sock_fd,(struct sockaddr *)&addr_server,sizeof(struct sockaddr_in))<0 )   //第二个参数需要强转,成功返回0失败返回-1
    {
		perror("bind error");
		exit(1);
	} 
    else
    {	
		printf("bind sucess\n");
	}
	while(1)		//循环接收发送数据
    {
		printf("begin recv:\n");
		recv_num = recvfrom(sock_fd,recv_buf,sizeof(recv_buf),0,(struct sockaddr *)&addr_client,&client_addrlen);
		if(recv_num < 0)
        {
			printf("recvfrom error\n");
			perror("again recvfrom");
			exit(1);
		} 
        else
        {
			printf("recvfrom sucess,data len is %d:%s\n",recv_num,recv_buf);
		    printf("begin send to ack:\n");
		    send_num = sendto(sock_fd,ack_buf,sizeof(ack_buf),0,(struct sockaddr *)&addr_client,client_addrlen);
            if(send_num < 0)
            {
                perror("sendto");
                exit(1);
            }
            else
            {
                printf("send ack success:%s\n",ack_buf);
            }
		}	 
	}
	close(sock_fd);
	return 0;
}